package calvin.study.springboot.config.aop;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

//声明一个切面类
@Aspect
public class LogAspects {
	
	//抽取公共的切入点表达式
	//1、本类引用 本来引用在表达式中写 “pointCut()”即可
	//2、其他的切面引用 其他类引用“calvin.study.springboot.aop.LogAspects.pointCut()”
	@Pointcut("execution(public int calvin.study.springboot.config.aop.MathCalculator.*(..))")
	public void pointCut() {}
	
	@Before(value = "pointCut()")
	public void logStart(JoinPoint joinPoint) {
		//获取方法名
		String method = joinPoint.getSignature().getName();
		//获取方法的参数
		Object[] args = joinPoint.getArgs();
		System.out.println("【前置通知】method：" + method + " args: "+ Arrays.asList(args));
	}
	
	@After(value = "calvin.study.springboot.config.aop.LogAspects.pointCut()")
	public void logEnd(JoinPoint joinPoint) {
		System.out.println("【后置通知】 method：" + joinPoint.getSignature().getName());
	}
	
	//returning="指定返回值" 接收返回值
	@AfterReturning(value="pointCut()",returning="result")
	public void logReturn(JoinPoint joinPoint,Object result) {
		System.out.println("【返回通知】：" + "返回值：" + result);
	}
	
	//throwing 接收异常
	@AfterThrowing(value="pointCut()",throwing="exception")
	public void logException(JoinPoint joinPoint,Exception exception) {
		System.out.println("【异常通知】：" + "异常：" +  exception);
	}

	
	@Around(value="pointCut()")
	public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("【环绕通知】~ 方法执行前");
		joinPoint.proceed();
		System.out.println("【环绕通知】~ 方法执行后");
		System.out.println();
	}
}
